
Type TColor
	Field	red:Int,green:Int,blue:Int

	Method Set(rgb:Int)
		red=(rgb Shr 16)&255
		green=(rgb Shr 8)&255
		blue=rgb&255
	End Method
End Type

Type TTextStyle
	Field	color:TColor
	Field	flags:Int
	
	Method Set(rgb:Int,bolditalic:Int)
		color.set(rgb)
		flags=bolditalic
	End Method

	Method Format(textarea:TGadget,pos:Int,length:Int)
		FormatTextAreaText textarea,color.red,color.green,color.blue,flags,pos,length
	End Method

	Function Create:TTextStyle()
		Local	s:TTextStyle
		s=New TTextStyle
		s.color=New TColor
		Return s
	End Function

End Type

function IsKeyword:int (test$)
	local keywords:String[] = ["break", "do", "end", "else", "elseif", "function", "if", "local", "nil", "not", "or", "repeat", "return", "then", "until", "while" ]
	for local s$ = eachin keywords
		if test = s then return true
	next
	return false
end function

' rem and endrem must be first nonwhitespace on line - following funcs are for lowercase src only
rem
	Function FindRem:Int(src$ , pos:Int) 
		Assert src=src.tolower() ' src is assumed to be lowercase on input!		
		While pos<=src.length
			pos=FindToken("rem",src,pos)
			If pos=src.length Exit
			If IsFirstCharOnLine(src,pos) Return pos
			pos:+1
		Wend
		Return pos
	End Function

	Function FindEndRem:Int(src$,pos:Int,returnlast:Int=False)
		Local	i:Int , c:Int
		
		Assert src=src.tolower() ' src is assumed to be lowercase on input!
		
		While pos<=src.length
			pos=FindEndToken("rem",src,pos)
			If pos=src.length Exit
			If IsFirstCharOnLine(src,pos)
				If returnlast
					If src[pos+5]=Asc("e") Or src[pos+5]=Asc("E") pos:+1
					pos:+6
					If pos<src.length Then
						Local qq:Int=src.find(EOL,pos)
						If qq>pos Then pos=qq
					End If

				EndIf
				Return pos
			EndIf
			pos:+1
		Wend
		Return src.length
	End Function

	Function FindPrevRem:Int(src$,pos:Int)	'lowercase src only!
		Local	p:Int , c:Int
		
		Assert src=src.tolower() ' src is assumed to be lowercase on input!		
		pos:+3 ' allow for the 3 chars of Rem
		If pos>=src.length Then pos=src.length
		While pos>=0
			p=src.FindLast("rem",src.length-pos) ' second param is chars from end to work back from
			If p=-1 Exit
			If (p=src.length-3 Or isnotalphanumeric(src[p+3])) And IsFirstCharOnLine(src,p) Return p
			pos=p-1
		Wend
		Return -1
	End Function
endrem

'Code from MaxIde Community Edition.
function HighlightRegion(_textarea:TGadget, src$ , p:Int , p1:Int)
		local EOL$ = "~n"
		Local lsrc$
		'Local style:TTextStyle[4] , s:TTextStyle
		Local t$ , h$ , a:Int
		Local q:Int,r:Int
		
DebugLog "Highlighting from "+p+" to "+p1		
		
		' let's just grab a few things for convenience...
		'style = options_editor.styles
		local quotedStyle:TTextStyle = TTextStyle.Create()
		quotedStyle.Set($ff00ff, TEXTFORMAT_ITALIC)
		
		local normalStyle:TTextStyle = TTextStyle.Create()
		normalStyle.Set($ffffff, 0)
		
		local commentStyle:TTextStyle = TTextStyle.Create()
		commentStyle.Set($AAAA00, 0)
		
		local numeralStyle:TTextStyle = TTextStyle.Create()
		numeralStyle.Set($0050B4, 0)
		
		local keywordStyle:TTextStyle = TTextStyle.Create()
		keywordStyle.Set($0000ff, 0)
		'lsrc = src.ToLower()
		
		
				
		' now lets get on with highlighting code
		's = style[options_editor.NORMAL]
		local s:TTextStyle = normalStyle
		If p1 > p Then s.Format(_textarea , p , p1 - p) 
		While p<p1
			'host.UpdateProgress("Highlighting Code",(p*100)/p1)
			a = src[p]	
			
' quoted strings
			If a=Asc("~q") Then
				q=p1
				r=src.find( "~q",p+1)
				If r>-1 And r<q q=r+1
				r=src.find(EOL,p+1)
				If r>-1 And r<q q=r
				's=style[options_editor.QUOTED]
				s = quotedStyle
				s.Format(_textarea,p,q-p)
				p=q
				Continue
			EndIf
' quoted chars
			If a=Asc("'") Then
				q=p1
				r=src.find( "'",p+1)
				If r>-1 And r<q q=r+1
				r=src.find(EOL,p+1)
				If r>-1 And r<q q=r
				's=style[options_editor.QUOTED]
				s = quotedStyle
				s.Format(_textarea,p,q-p)
				p=q
				Continue
			EndIf
			
' macroes
rem
			If a=Asc("#") Then
				'TODO: (TCCodePanel) syntax highlight multiline macroes
				q=p1
				r=src.find(EOL,p+1)
				If r>-1 And r<q q=r
				's=style[options_editor.ATTRIBUTE]
				s = quotedStyle
				s.Format(_textarea,p,q-p)
				p=q
				Continue
			EndIf
end rem	
' comments
			If a = Asc("-") Then
				q = p + 1
				If q >= src.length Then p:+ 1 ; Continue
				Select src[q]
					Case Asc("-") ' single line comments
						q :+ 1
						r=src.find( EOL,q)
						If r <> -1 Then q=r
						's=style[options_editor.COMMENT]
						s = commentStyle
						s.Format(_textarea,p,q-p)
						p=q
						Continue
					rem
					Case Asc("*") ' multiline comments
						q :+ 1
						r = FindEndRem( src, q)
						If r <> -1 Then
							q=r+2
							's=style[options_editor.COMMENT]
							s = commentStyle
							s.Format(_textarea,p,q-p)
							p=q
							Continue
						EndIf
					endrem
				EndSelect
			EndIf
			

' hexadecimal numbers
			If a = Asc("0") And src[p+1] = Asc("x") Then
				q = p + 2

				While q < p1
					a = src[q]
					If a < 48 Or (a > 57 And ((a & $DF) < 65 Or (a & $DF) > 70)) Then Exit
					q :+ 1
				Wend

				If q > p + 1
					's = style[options_editor.NUMERAL]
					s = numeralStyle
					s.Format(_textarea, p, q - p)
				EndIf

				p = q
				Continue
			EndIf			

' decimal numbers
			If 48 <= a And a <= 57
				q=p+1
				While q<p1
					a=src[q]
					If a < 48 Or 57 < a Then Exit
					q:+1
				Wend
				's=style[options_editor.NUMERAL]
				s = numeralStyle
				s.Format(_textarea,p,q-p)
				p=q
				Continue
			EndIf

' tokens
			If (a>=65 And a<91) Or (a>=97 And a<123) Or (a=95)
				q=p+1
				While q<p1
					a=src[q]
					If a<48 Exit
					If a>=58 And a<65 Exit
					If a>=91 And a<95 Exit
					If a=96 Exit
					If a>122 Exit
					q:+1
				Wend
				t$ = src[p..q]
				If IsKeyword(t$) Then					
					's=style[options_editor.KEYWORD]
					s = numeralStyle
					s.Format(_textarea , p , q - p) 							
				EndIf
				p=q
				Continue
			EndIf
			p:+1
		Wend
	endfunction 
